Skip to content

fix(desktop): 修复 macOS 首屏与受控退出 - #18

Merged
generalio merged 2 commits into
mainfrom
generalio/fix/desktop-macos-lifecycle
Aug 7, 2026
Merged

fix(desktop): 修复 macOS 首屏与受控退出#18
generalio merged 2 commits into
mainfrom
generalio/fix/desktop-macos-lifecycle

Conversation

@generalio

@generalio generalio commented Aug 7, 2026

Copy link
Copy Markdown
Owner

目的

修复 macOS Compose Desktop 中 JCEF windowed WebView 首次进入黑屏、调整窗口后才显示的问题,并将窗口关闭与 Cmd+Q 统一为受控退出流程,降低 AppKit/JCEF 清理竞争导致 NSEvent.removeMonitor 原生崩溃的风险。

改动内容

  • 初始布局协调器同时监听 Swing showing 与首次有效尺寸;满足条件后仅一次执行 revalidate() -> paintImmediately() -> repaint()
  • 新增 DesktopWebViewRuntime.createMacOsTerminationHandler()bindApplicationExit()requestApplicationExit()
  • Compose Runtime 按控制器对象身份追踪 active/closing 状态,仅在全部浏览器正常关闭后调用一次 CefApp.dispose(),并等待 TERMINATED 后执行宿主退出回调。
  • 示例改用新的 macOS 终止处理器与受控退出入口。
  • 更新 JVM API 基线、README、使用指南和架构说明。

兼容性:保留既有 initialize(cefApp, onBrowserClosed) 签名与行为;新增 API 仅位于 Desktop JVM Runtime,不影响 common、Android、iOS、JS/Wasm。

平台影响

  • Android:无代码行为改动。
  • iOS:无代码行为改动。
  • Desktop:修复首次有效尺寸晚于 JCEF 创建时的首屏同步;macOS 可显式接入受控退出。
  • JS/Wasm:无代码行为改动。

验证命令与结果

  • ./gradlew :webview-desktop:test --stacktrace --console=plain --no-configuration-cache:通过。
  • ./gradlew :webview-compose:jvmTest --stacktrace --console=plain --no-configuration-cache:通过。
  • ./gradlew :sample-compose:compileKotlinDesktop --stacktrace --console=plain --no-configuration-cache:通过。
  • ./gradlew :sample-compose:desktopTest --stacktrace --console=plain --no-configuration-cache:通过。
  • ./gradlew :webview-compose:jvmApiCheck --stacktrace --console=plain --no-configuration-cache:通过。
  • ./gradlew :webview-compose:apiCheck --stacktrace --console=plain --no-configuration-cache:JVM/Android API 阶段通过;iOS cinterop 被本机缺失 Xcode 阻断(xcrun xcodebuild exit 72),与本次 Desktop 改动无关。
  • git diff --check:通过。

未执行真实 macOS JCEF 回归;合并前请验证首次进入无需调整窗口、连续进出、Window 关闭、Cmd+Q,以及 WebView 打开/返回页面后的退出。

风险与兼容性

  • 仅 macOS 的 createMacOsTerminationHandler() 返回 true 拦截 JCEF 默认终止;非 macOS 保持默认行为。
  • 新受控退出方式要求宿主在退出前调用一次 bindApplicationExit(::exitApplication),且不得同时在旧 onBrowserClosed 回调中自行销毁 CEF。
  • 控制器仍使用既有 close(false) 路径,不切换 OSR、不使用强制关闭。
  • 不涉及 JS 桥、Cookie、文件访问、下载或外部导航安全策略变更。

文档变更

  • README:补充 Desktop Compose 受控退出接入示例。
  • docs/使用指南.md:说明 Runtime API、定制终止处理器与 macOS 启动顺序。
  • docs/架构说明.md:更新 Desktop 首屏同步与进程级退出职责。

Copilot AI lite review requested due to automatic review settings August 7, 2026 16:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@generalio
generalio merged commit e7ca3ef into main Aug 7, 2026
2 checks passed
@generalio
generalio deleted the generalio/fix/desktop-macos-lifecycle branch August 7, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants